﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Data;

namespace AgileShare.Framework.Library.Helpers
{
    public class SPPagedListItemsHepler
    {
        private SPQuery _query;
        private SPList _list;
        private const int MaxRowLimit = 2000;
        private static SPListItemCollectionPosition _emptySPListItemCollectionPosition = new SPListItemCollectionPosition(string.Empty);

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="list"></param>
        /// <param name="query"></param>
        public SPPagedListItemsHepler(SPList list, SPQuery query)
        {
            _list = list;
            _query = query;
        }

        /// <summary>
        /// 获取数据返回数组
        /// </summary>
        /// <param name="startIndex"></param>
        /// <param name="maxRowsCount"></param>
        /// <returns></returns>
        public SPListItem[] GetItemsReturnArray(int? startIndex, int? maxRowsCount)
        {
            List<SPListItem> returnedItemsList = new List<SPListItem>();
            var listItems = GetItems(startIndex, maxRowsCount);
            returnedItemsList.AddRange(listItems.Cast<SPListItem>().Select(i => i));
            return returnedItemsList.ToArray();
        }

        /// <summary>
        /// 获取数据返回DataTable
        /// </summary>
        /// <param name="startIndex"></param>
        /// <param name="maxRowsCount"></param>
        /// <returns></returns>
        public DataTable GetItemsReturnDataTable(int? startIndex, int? maxRowsCount)
        {

            string ITEM_LINK_URL = "GOTO_ITEM_URL";
            string ITEM_ENCODED_ABS_URL = "EncodedAbsUrl";

            DataTable dt = new DataTable();

            var listItems = GetItems(startIndex, maxRowsCount);
            var fieldsNameCollection = listItems.QueryFieldNames;
            for (int i = 0; i < fieldsNameCollection.Count; i++)
            {
                if (fieldsNameCollection[i].StartsWith("ows_"))
                    fieldsNameCollection[i] = fieldsNameCollection[i].Remove(0, 4);
                dt.Columns.Add(new DataColumn(fieldsNameCollection[i]));
            }
            dt.Columns.Add(new DataColumn(ITEM_LINK_URL));

            foreach (SPListItem item in listItems)
            {
                DataRow dr = dt.NewRow();
                for (int i = 0; i < fieldsNameCollection.Count; i++)
                {
                    SPField field = _list.Fields.GetFieldByInternalName(fieldsNameCollection[i]);
                    if (field == null)
                        throw new Exception();

                    if (field is SPFieldLookup)
                    {
                        SPFieldLookup lf = (SPFieldLookup)field;
                        dr[field.InternalName] = lf.GetFieldValueAsText(item[field.InternalName]);
                    }
                    else if (field is SPFieldUrl)
                    {
                        SPFieldUrl lf = (SPFieldUrl)field;
                        dr[field.InternalName] = lf.GetFieldValueAsHtml(item[field.InternalName]);
                    }
                    else dr[field.InternalName] = item[field.InternalName];
                }

                if (_list.BaseTemplate == SPListTemplateType.DocumentLibrary ||
                    _list.BaseTemplate == SPListTemplateType.PictureLibrary)
                {
                    dr[ITEM_LINK_URL] = item[ITEM_ENCODED_ABS_URL];
                }
                else
                {
                    dr[ITEM_LINK_URL] = String.Concat(item.Web.Url, "/",
                        item.ParentList.Forms[PAGETYPE.PAGE_DISPLAYFORM].Url,
                        "?id=", item.ID.ToString());
                }
                dt.Rows.Add(dr);
            }
            return dt;
        }


        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="startIndex"></param>
        /// <param name="maxRowsCount"></param>
        /// <returns></returns>
        public SPListItemCollection GetItems(int? startIndex, int? maxRowsCount)
        {
            DataTable result = new DataTable();

            SPListItemCollectionPosition listItemCollectionPosition = null;
            uint actualStartIndex = startIndex.HasValue ? (uint)startIndex.Value : 0;

            if (actualStartIndex > 0)
            {
                SPQuery dummyQuery = new SPQuery();
                dummyQuery.ViewFields = "<FieldRef Name='ID' />";
                dummyQuery.Query = _query.Query;
                if (null != _query.Folder)
                    dummyQuery.Folder = _query.Folder;
                int gotDummyItems = 0;
                do
                {
                    dummyQuery.RowLimit = Math.Min((uint)(actualStartIndex - gotDummyItems), MaxRowLimit);
                    if (null == listItemCollectionPosition)
                        listItemCollectionPosition = _emptySPListItemCollectionPosition;

                    dummyQuery.ListItemCollectionPosition = listItemCollectionPosition;
                    SPListItemCollection items = _list.GetItems(dummyQuery);
                    gotDummyItems += items.Count;
                    listItemCollectionPosition = items.ListItemCollectionPosition;
                }
                while (gotDummyItems < actualStartIndex && listItemCollectionPosition != null);
            }

            SPQuery query = new SPQuery();
            query.Query = _query.Query;
            if (null != _query.Folder)
                query.Folder = _query.Folder;
            query.ViewFields = _query.ViewFields;
            List<SPListItem> returnedItemsList = new List<SPListItem>();
            uint actualMaxRowCount = maxRowsCount.HasValue ? (uint)maxRowsCount.Value : (uint)_list.ItemCount;

            SPListItemCollection listItems;
            do
            {
                query.RowLimit = Math.Min(actualMaxRowCount, MaxRowLimit);
                if (null == listItemCollectionPosition)
                    listItemCollectionPosition = _emptySPListItemCollectionPosition;
                query.ListItemCollectionPosition = listItemCollectionPosition;
                listItems = _list.GetItems(query);
                returnedItemsList.AddRange(listItems.Cast<SPListItem>().Select(i => i));
                listItemCollectionPosition = listItems.ListItemCollectionPosition;
            }
            while (returnedItemsList.Count < actualMaxRowCount && listItemCollectionPosition != null);
            return listItems;
        }

        /// <summary>
        /// 获取数据总数
        /// </summary>
        /// <returns></returns>
        public int GetTotalItemsCount()
        {
            SPQuery query = new SPQuery();
            query.ViewFields = "<FieldRef Name='ID' />";
            query.Query = _query.Query;
            SPFolder folder = _query.Folder;
            if (null != folder)
                query.Folder = folder;
            return _list.GetItems(query).Count;
        }
    }
}
